package com.heima.behavior.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.behavior.dto.ArticleOperationMessage;
import com.heima.behavior.dto.LikesBehaviorDto;
import com.heima.behavior.entity.ApLikesBehavior;
import com.heima.behavior.mapper.ApLikesBehaviorMapper;
import com.heima.behavior.service.IApLikesBehaviorService;
import com.heima.common.dto.ResponseResult;
import com.heima.common.dto.User;
import com.heima.common.util.UserThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

/**
 * <p>
 * APP点赞行为表 服务实现类  查阅 收藏 评论 代码一样同点赞
 * </p>
 *
 * @author itheima
 * @since 2022-08-07
 */
@Service
public class ApLikesBehaviorServiceImpl extends ServiceImpl<ApLikesBehaviorMapper, ApLikesBehavior> implements IApLikesBehaviorService {


    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate; //用于发消息
 //发送的消息需包含增量值是增加还是减少 add:数字  对应点赞和取消点赞 喜不喜欢 包含articleId文章id 包含 操作类型 type 如类型是查阅 点赞 评论 收藏
    /**
     * 文章得分话题-原始话题
     */
    @Value("${topic.hotArticleScoreTopic}") //从behavior模块的Yml topic找到此话题 通过@Value获取
    private String hotArticleScoreTopic;


    /**
     * 保存点赞记录，将点赞数据存入Redis缓存
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveLikes(LikesBehaviorDto dto) {
        User user = UserThreadLocalUtil.get();
        if (user == null) {
            return ResponseResult.errorResult(401, "请登录后操作！");
        }
        //1.构建点赞Key
        String redisKey = "leadnews:article:like:" + dto.getArticleId();//用户id也可
        if (dto.getOperation() == 0) { //如果是点赞
            redisTemplate.opsForSet().add(redisKey, user.getUserId().toString());//redisKey第一位写的目的是标识文章 这篇文章被哪些用户有过点赞记录，第二位是有哪些用户进行过点赞--目前仅这一个用户
        } else { //如果是取消点赞 则删除 redis中SET集合中的元素 不是删除key即可
            redisTemplate.opsForSet().remove(redisKey, user.getUserId().toString());
        }
        //TODO 将点赞（和取消点赞）行为 都要 发送到Kafka话题中 即发送到原始话题中
        ArticleOperationMessage operationMessage = new ArticleOperationMessage();
        operationMessage.setArticleId(dto.getArticleId());
        operationMessage.setType(1); //ArticleOperationMessage类定义的 type =1 是点赞 其他很多类type定义的各不同很相似易乱注意写
        operationMessage.setAdd(dto.getOperation() == 0 ? 1 : -1); //需看LikesBehaviorDto的operation 0 点赞 1取消点赞  设置增量值  喜欢的操作方式 0是点赞 1是取消点赞  等于0是点赞则返回值是1 则增量值加1 等于其他值则是取消点赞是不喜欢返回-1 增量值减一
        kafkaTemplate.send(hotArticleScoreTopic, JSON.toJSONString(operationMessage));//第一个是话题，第二个是把要发的消息对象转成JSON    if想取到则取的那个操作需要反序列化ArticleOperationMessage再转回java对象才能取值
        return ResponseResult.okResult();
    }  // 点赞和取消点赞效果去看redis里的值变化 ，而看有没发到原始话题 话题这类的则去kafkadrop界面去看 view message
     //在此次话题下hotArticleScoreTopic下 会产生大量操作行为，此行为是实时发生的，因为不一定有哪些用户操作对哪些文章进行过什么操作，都会记录在此话题中
     // 点赞代码 和 查阅阅读 收藏 评论 代码一样 知一会多 都是都要发消息到Kafka话题中是hotArticleScoreTopic中
}
